/* 从样式属性值中截取单位 */
// getUnit("200.123px")
function getUnit(value) {
    // 定义所有的数字
    var digits = "0123456789.-"

    // 将入参先转换为string（以便计算字符数）
    value = value + ""//200px

    /* 遍历入参的每一个字符 */
    for (var i = 0; i < value.length; i++) {
        // 提取出每一个字符
        var char = value[i]

        // 看看当前字符是否是【数字字符】
        // 如果不是【数字字符】 则当前位i一直到末尾皆为单位
        if (digits.includes(char) === false) {
            // 从当前位i一直截取到末尾 得到单位 返回之
            return value.slice(i)
        }

    }
    return ""
}

/**
 * 多属性动画
 * @param {Element} element 要做动画的元素
 * @param {Object} targetObj 属性目标值的对象 封装了所有要做动画的属性及其目标值
 * @param {number} timeCost 动画耗时，单位毫秒
 * @param {Function} callback 动画结束的回调函数
 * animate(box,{left:"200px",top:"500px",opacity:0.5},3000,()=>console.log("动画结束"))
 */
function animate(element, targetObj, timeCost = 1000, callback = null) {

    // 定义每帧时长为40毫秒
    var FRAEME_COST = 40

    // 计算总帧数（半帧按一帧算）3000/40
    var frames = Math.ceil(timeCost / FRAEME_COST)

    // 记录当前运行到了第几帧
    var currentFrame = 0

    // 提前拿到动画前所有CSS属性 {left:0,top:0,opacity:1...}
    var exStyles = window.getComputedStyle(element)

    /* 每个CSS属性每帧应该偏移多少 */
    // speed者 每帧偏移量也
    var speedObj = {}

    /* 计算每帧应该移动多少 */
    // key分别为 left top opacity
    for (var key in targetObj) {
        // 拿出left属性的目标值 200px
        var targetValue = targetObj[key]
        speedObj[key] = {
            // left每帧的偏移量
            offset: (parseFloat(targetValue) - parseFloat(exStyles[key])) / frames,

            // 将单位也揪出来
            unit: getUnit(targetValue)
        }
    }

    /* 开始做动画 */
    var timer = setInterval(

        /* 每40毫秒执行一下这个破函数：在上一帧(frame)的基础上 所有目标样式都按动画速度speedObj[key]偏移一丢丢 */
        function () {

            // 在每帧中对每个属性按动画速度做偏移
            for (var key in speedObj) {

                /* 拿出left属性每帧的偏移量 */
                var offset = speedObj[key].offset

                // 拿出left属性的单位
                var unit = speedObj[key].unit

                // 将元素的left设置为一个新的值（偏移了一丢丢）
                // element.style.left = (0+2)+"px"
                element.style[key] = parseFloat(getComputedStyle(element)[key]) + offset + unit
            }

            /* 看看够帧数了没有 */
            if (++currentFrame === frames) {
                // 帧数一满 停止动画
                clearInterval(timer)

                // 暴力矫正误差（将所有属性都打到目标值）
                // {left:"200px",top:"500px",opacity:0.5}
                for (var key in targetObj) {
                    // box.style.left = "200px"
                    element.style[key] = targetObj[key]
                }

                // 回调callback
                callback && callback()
            }
        },

        // 每40毫秒一帧
        FRAEME_COST
    );
}
